package cn.bob.basic.service.impl;

import cn.bob.basic.config.BussinessException;
import cn.bob.basic.constant.BaseConstant;
import cn.bob.basic.dto.LoginDto;
import cn.bob.basic.dto.RegisterDto;
import cn.bob.basic.utils.EmailUtil;
import cn.bob.basic.utils.StrUtils;
import cn.bob.basic.utils.VerifyCodeUtils;
import cn.bob.basic.service.IVerifyCodeService;
import cn.bob.user.domain.User;
import cn.bob.user.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author bob
 * @data 2022/10/18-15:20
 */
@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IUserService userService;

    /**
     * 图形验证码
     * @param uuidkey
     * @return
     */
    @Override
    public String graph(String uuidkey) {
        //通过工具类获取到随机字符
        String complexRandomString = StrUtils.getComplexRandomString(4);
        //将随机字符存储到redis中 设置生命周期为3分钟
        redisTemplate.opsForValue().set(uuidkey,complexRandomString,3, TimeUnit.MINUTES);
        //生成为base64返回
        return VerifyCodeUtils.VerifyCode(100,35,complexRandomString);
    }

    /**
     * 发送手机验证码
     * @param registerDto
     */
    @Override
    public void smsCode(RegisterDto registerDto) {
        //验证参数是否为空      已经验证过了通过@notnull注解
        // 正则表达式判断手机格式
        phoneFormat(registerDto);
        if (!"binder".equals(registerDto.getType())){
            //当前手机号是否注册
            User user=userService.findByPhone(registerDto.getPhone());
            if (null!=user){
                throw new BussinessException("手机号已经被注册");
            }
            imageVerify(registerDto);
            //校验两次验证码发送的间隔时间 存到reids中
            String randomCode = smsCodeLogin(String.format(BaseConstant.VerifyCodeCons.PHONE_REDIS_KEY, registerDto.getPhone()));
        }
        //是绑定保存redis
        String randomCode = smsCodeLogin(String.format(BaseConstant.VerifyWechat.PHONE_REDIS_VERIFYCODE, registerDto.getPhone()));
        System.out.println(randomCode);
        //发送短信
//        SendMsgUtil.sendsms(registerDto.getPhone(),"宠物之家的验证码为："+randomCode+",在5分钟内有效");
    }
    /**
     * 发送邮箱验证码
     * @param registerDto
     */
    @Override
    public void smsCodeEmail(RegisterDto registerDto) {
        //验证参数是否为空      已经验证过了通过@notnull注解
        //判断邮箱格式是否一致
        emailFormat(registerDto);
        //图形验证码是否正确
        imageVerify(registerDto);

        //校验两次验证码发送的间隔时间 存到reids中
        String randomCode = smsCodeLogin(String.format(BaseConstant.VerifyCodeCons.PHONE_REDIS_KEY, registerDto.getEmail()));

        //发送邮件
        try {
            EmailUtil.sendMail("209545769@qq.com",registerDto.getEmail(),"这是你的验证码"+randomCode,"D:/桌面/study/74882994_590610338351366_111836065010024448_o.jpg");
        }catch (BussinessException bx){throw new BussinessException(bx.getMessage());}
        catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 发送手机验证码手机验证码登录
     * @param registerDto
     */
    @Override
    public void smsCodeLogin(LoginDto registerDto) {
        // 正则表达式判断手机格式
        phoneFormat(registerDto);
        //发送两次验证码的间隔时间
        //通过BaseCopnstant的格式拼接上phone获取存储在redis中的手机注册的短信
        //通过key去value的值   验证码:时间戳
        smsCodeLogin(String.format(BaseConstant.VerifySmsCodeCons.PHONE_REDIS_KEY,registerDto.getPhone()));

        //发送短信
//        SendMsgUtil.sendsms(registerDto.getPhone(),"宠物之家的验证码为："+randomCode+",在5分钟内有效");

    }


    //图形验证码
    private void imageVerify(RegisterDto registerDto) {
        if(StringUtils.isBlank(registerDto.getImageCodeKey())){
            throw new BussinessException("uuid不能为空！！");
        }
        if (StringUtils.isBlank(registerDto.getImageCodeValue())){
            throw new BussinessException("图形验证码不能为空！！");
        }
        //图形验证码是否正确
        String imgcode = (String) redisTemplate.opsForValue().get(registerDto.getImageCodeKey());
        if (StringUtils.isBlank(imgcode) || !imgcode.equalsIgnoreCase(registerDto.getImageCodeValue())) {
            throw new BussinessException("验证码错误！！");
        }
    }

    // 正则表达式判断手机格式
    private void phoneFormat(RegisterDto registerDto) {
        //判断手机不能为空
        if (StringUtils.isBlank(registerDto.getPhone())){
            throw new BussinessException("手机不能为空！！");
        }
        //判断手机格式
        Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
        Matcher m = p.matcher(registerDto.getPhone());
        boolean matches = m.matches();
        if (!matches){
            throw new BussinessException("手机格式错误！！");
        }

    }
    // 正则表达式判断手机格式
    private void phoneFormat(LoginDto registerDto) {
        //判断手机不能为空
        if (StringUtils.isBlank(registerDto.getPhone())){
            throw new BussinessException("手机不能为空！！");
        }
        //判断手机格式
        Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0-9]))\\d{8}$");
        Matcher m = p.matcher(registerDto.getPhone());
        boolean matches = m.matches();
        if (!matches){
            throw new BussinessException("手机格式错误！！");
        }
        //当前手机号是否注册
        User user=userService.findByPhone(registerDto.getPhone());
        if (null==user){
            throw new BussinessException("手机号未注册！！");
        }
    }

    //判断邮箱格式是否一致 以及是否被注册
    private void emailFormat(RegisterDto registerDto) {
        //判断邮箱不能为空
        if (StringUtils.isBlank(registerDto.getEmail())){
            throw new BussinessException("邮箱不能为空！！");
        }
        //判断邮箱格式是否一致
        String tegex="[\\w!#$%&'*+/=?^_`{|}~-]+(?:\\.[\\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\\w](?:[\\w-]*[\\w])?\\.)+[\\w](?:[\\w-]*[\\w])?";
        boolean flag= registerDto.getEmail().matches(tegex);
        System.out.println(!flag);
        if (!flag){
            throw new BussinessException("邮箱格式错误！！");
        }
        //当前邮箱是否注册
        User user=userService.findByEmail(registerDto.getEmail());
        if (null!=user){
            throw new BussinessException("邮箱已经被注册");
        }
    }

    //发送两次验证码的间隔时间  手机验证码登录
    private String smsCodeLogin(String  phoneRedisCode) {
        String Code = (String) redisTemplate.opsForValue().get(phoneRedisCode);
        if (StringUtils.isNotBlank(Code)){
            //判断redis中取出来的是否为空不为空
            String[] split = Code.split(":");
            long newTime= System.currentTimeMillis();
            long oldTime = Long.valueOf(split[1]);
            if (newTime-oldTime<60*1000){
                throw new BussinessException("请一分钟后重试！！");
            }
        }
        //取出的值为空生成验证码
        String randomCode = StrUtils.getRandomString(4);
        Code=randomCode+":"+System.currentTimeMillis();
        log.info("验证码：{} ",randomCode);
        //存入到redis中
        redisTemplate.opsForValue().set(phoneRedisCode,Code,5, TimeUnit.MINUTES);
        return randomCode;
    }


}
